/*
    This file is part of ciberRatoToolsSrc.

    Copyright (C) 2001-2007 Universidade de Aveiro

    ciberRatoToolsSrc is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    ciberRatoToolsSrc is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Foobar; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
// cbsimulatorGUI.cpp
//
// application main window
//
// creates menus, toolbar 
//

#include <qapplication.h>
#include <qtoolbar.h>
#include <qpopupmenu.h>
#include <qaction.h>
#include <qmenubar.h>
#include <qmessagebox.h>
#include <qtextview.h>
#include <qfiledialog.h>
#include <qstylesheet.h>

#include "cbsimulator.h"
#include "cbrobot.h"
#include "cbparamdialog.h"
#include "cbsimulatorGUI.h"


/** 
 * cbSimulatorGUI contructor.
 */
cbSimulatorGUI::cbSimulatorGUI( cbSimulator *sim, QWidget* parent,  const char* name, WFlags fl )
    : QMainWindow( parent, name, fl ), simulator(sim)
{
	setCaption("CiberRato 2008 simulator");

	messages = new QTextView( this, "workspace" );
	messages->setTextFormat(PlainText);
	messages->setText("Messages:");

        //// Main menus
	//file
	QPopupMenu *fileMenu = new QPopupMenu( this );
	menuBar()->insertItem( "&File", fileMenu );

	//command
	QPopupMenu *commandMenu = new QPopupMenu( this );
	menuBar()->insertItem( "&Command", commandMenu );

	menuBar()->insertSeparator();

        //help
	QPopupMenu *helpMenu = new QPopupMenu( this );
	helpMenu->insertItem("&About", this, SLOT(about()), Key_F1);
	menuBar()->insertItem( "&Help", helpMenu );


        //// Toolbar
	//QToolBar *cbToolBar = new QToolBar( this );
	//addToolBar( cbToolBar, "cbToolbar" );


        //// Actions
	QAction *action = 0;


        //Open Lab
	action = new QAction( "Open Lab", "Open &Lab", 0, this );
	action->addTo( fileMenu );
	connect( action, SIGNAL( activated() ), this, SLOT( changeLab() ) );
        //Open Grid
	action = new QAction( "Open Grid", "Open &Grid", 0, this );
	action->addTo( fileMenu );
	connect( action, SIGNAL( activated() ), this, SLOT( changeGrid() ) );
        //Open Configuration
	action = new QAction( "Open Configuration", "Open &Configuration", 0, this );
	action->addTo( fileMenu );
	connect( action, SIGNAL( activated() ), this, SLOT( changeParameters() ) );
        //Change Configuration
	action = new QAction( "Edit Configuration", "Edit Configuration", 0, this );
	action->addTo( fileMenu );
	connect( action, SIGNAL( activated() ), this, SLOT( editParameters() ) );
        //Save Configuration
	action = new QAction( "Save Configuration", "Save Configuration", 0, this );
	action->addTo( fileMenu );
	connect( action, SIGNAL( activated() ), this, SLOT( saveConfiguration() ) );
        //Toggle GPS state
	action = new QAction( "GPS Enabled", "GP&S Enabled", 0, this );
	action->setToggleAction(true);
	action->setOn(simulator->getGPS());
	action->addTo( fileMenu );
	connect( action, SIGNAL( toggled(bool) ), this, SLOT( toggleGPS(bool) ) );
	actGPSToggle = action;
        //Toggle Score Sensor state
	action = new QAction( "Score Sensor Enabled", "S&core Sensor Enabled", 0, this );
	action->setToggleAction(true);
	action->setOn(simulator->getScoreSensor());
	action->addTo( fileMenu );
	connect( action, SIGNAL( toggled(bool) ), this, SLOT( toggleScoreSensor(bool) ) );
	actScoreSensorToggle = action;
        //exit
	action = new QAction( "Exit", "E&xit", 0, this );
	action->addTo( fileMenu );
	connect( action, SIGNAL( activated() ), qApp, SLOT( closeAllWindows() ) );

        //Reset
	action = new QAction( "Reset", "&Reset", 0, this );
	action->addTo( commandMenu );
	connect( action, SIGNAL( activated() ), simulator, SLOT( reset() ) );
        //Start
	action = new QAction( "Start", "&Start", 0, this );
	action->addTo( commandMenu );
	connect( action, SIGNAL( activated() ), simulator, SLOT( start() ) );
        //Stop
	action = new QAction( "Stop", "S&top", 0, this );
	action->addTo( commandMenu );
	connect( action, SIGNAL( activated() ), simulator, SLOT( stop() ) );

	setCentralWidget( messages );
}

/*  
 *  Destroys the object and frees any allocated resources
 */
cbSimulatorGUI::~cbSimulatorGUI()
{
    // no need to delete child widgets, Qt does it all for us
}

void cbSimulatorGUI::changeLab(void)
{
    if(simulator->state()==cbSimulator::INIT) {
       // start at the current working directory and with *.xml as filter
       QString f = QFileDialog::getOpenFileName( QString::null, "*.xml", this );
       if ( !f.isEmpty() ) {
           messages->update();
   	   if(simulator->changeLab(f))
	       messages->append((QString("Lab Changed to ")+f));
      	   else
   	       messages->append((QString("Error loading ")+f));
           messages->update();
       }
    }
    else {
	messages->append(QString("Cannot Change Lab After Start - Use Reset"));
    }
}

void cbSimulatorGUI::changeGrid(void)
{
    if(simulator->state()==cbSimulator::INIT) {
	// start at the current working directory and with *.xml as filter
	QString f = QFileDialog::getOpenFileName( QString::null, "*.xml", this );
	if ( !f.isEmpty() ) {
	    messages->update();
	    if(simulator->changeGrid(f))
	        messages->append((QString("Grid Changed to ")+f));
	    else
	        messages->append((QString("Error loading ")+f));
	    messages->update();
        }
    }
    else {
	messages->append(QString("Cannot Change Grid After Start - Use Reset"));
    }
}

void cbSimulatorGUI::changeParameters(void)
{
    if(simulator->state()==cbSimulator::INIT) {
        // start at the current working directory and with *.cpp as filter
        QString f = QFileDialog::getOpenFileName( QString::null, "*.xml", this );
        if ( !f.isEmpty() ) {
            messages->update();
	    if(simulator->changeParameters(f))
	        messages->append((QString("Parameters Changed to ")+f));
	    else
	        messages->append((QString("Error loading ")+f));
            messages->update();
        }
    }
    else {
	messages->append(QString("Cannot Change Parameters After Start - Use Reset"));
    }
}

void cbSimulatorGUI::editParameters(void)
{
    if(simulator->state()==cbSimulator::INIT) {
        // start at the current working directory and with *.cpp as filter
	
	cbParamDialog paramDlg(simulator->getParameters());

	paramDlg.exec();

	simulator->processEditParameters();
    }
    else {
	messages->append(QString("Cannot Change Configuration After Start - Use Reset"));
    }
}

void cbSimulatorGUI::saveConfiguration(void)
{
    if(simulator->state()==cbSimulator::INIT) {
	    
        QString f = QFileDialog::getSaveFileName( QString::null, "*.xml", this );
	
	simulator->saveConfiguration(f);
    }
    else {
	messages->append(QString("Cannot Save Configuration After Start - Use Reset"));
    }
}

void cbSimulatorGUI::toggleGPS(bool g)
{
    if(simulator->state()==cbSimulator::INIT) {
        actGPSToggle->setOn(g);
	simulator->setGPS(g);
	cbRobot::GPSOn = g;
    }
    else {
	messages->append(QString("Cannot Change Configuration After Start - Use Reset"));
	actGPSToggle->setOn(cbRobot::GPSOn);
    }
}

void cbSimulatorGUI::toggleScoreSensor(bool g)
{
    if(simulator->state()==cbSimulator::INIT) {
        actScoreSensorToggle->setOn(g);
	simulator->setScoreSensor(g);
	cbRobot::scoreSensorOn = g;
    }
    else {
	messages->append(QString("Cannot Change Configuration After Start - Use Reset"));
	actScoreSensorToggle->setOn(cbRobot::scoreSensorOn);
    }
}

void cbSimulatorGUI::about(void)
{
    QMessageBox::about(this,"About CiberRato 2008 simulator",
         "<b>CiberRato 2008 simulator</b><br>"
	 "Copyright 2001-2008 Universidade de Aveiro<br>"
	 "Universidade de Aveiro<br>"
	 "http://microrato.ua.pt<br>"
	 "http://robotica.ua.pt/robotica2008"
	 );

}
